import Browser from './browser';
import { cleanUp } from './functions';

const Print = {
  send: (params, printFrame) => {
    // Append iframe element to document body
    document.getElementsByTagName('body')[0].appendChild(printFrame);

    // Get iframe element
    const iframeElement = document.getElementById(params.frameId);

    // setTimeout(() => {
    // Wait for iframe to load all content
    iframeElement.onload = () => {
      if (params.type === 'pdf') {
        performPrint(iframeElement, params);
        return;
      }

      // Get iframe element document
      let printDocument = iframeElement.contentWindow || iframeElement.contentDocument;
      if (printDocument.document) printDocument = printDocument.document;

      // Append printable element to the iframe body
      printDocument.body.appendChild(params.printableElement);

      // Add custom style
      if (params.type !== 'pdf' && params.style) {
        // Create style element
        const style = document.createElement('style');
        style.innerHTML = params.style;

        // Append style element to iframe's head
        printDocument.head.appendChild(style);
      }

      // If printing images, wait for them to load inside the iframe
      const images = printDocument.getElementsByTagName('img');

      if (images.length > 0) {
        loadIframeImages(images).then(() => performPrint(iframeElement, params));
      } else {
        performPrint(iframeElement, params);
      }
    };
    // }, 10)
  },
};

function performPrint(iframeElement, params) {
  try {
    iframeElement.focus();

    // If Edge or IE, try catch with execCommand
    if (Browser.isEdge() || Browser.isIE()) {
      try {
        iframeElement.contentWindow.document.execCommand('print', false, null);
      } catch (e) {
        iframeElement.contentWindow.print();
      }
    } else {
      // Other browsers
      iframeElement.contentWindow.print();
    }
  } catch (error) {
    params.onError(error);
  } finally {
    cleanUp(params);
  }
}

function loadIframeImages(images) {
  const promises = [];

  for (let i = 0; i < images.length; i++) {
    promises.push(loadIframeImage(images[i]));
  }

  return Promise.all(promises);
}

function loadIframeImage(image) {
  return new Promise((resolve) => {
    const pollImage = () => {
      !image || typeof image.naturalWidth === 'undefined' || image.naturalWidth === 0 || !image.complete ? setTimeout(pollImage, 500) : resolve();
    };
    pollImage();
  });
}

export default Print;
